"""
通道控制面板模块
"""

import tkinter as tk
from tkinter import ttk
import numpy as np
import cv2
from PIL import Image, ImageTk

from ...utils import get_logger


class ChannelControlPanel:
    """通道控制面板类"""
    
    def __init__(self, parent: ttk.Frame, image: np.ndarray, on_update_callback):
        """
        初始化通道控制面板
        
        Args:
            parent: 父容器
            image: 原始图片 (RGB)
            on_update_callback: 更新回调函数
        """
        self.parent = parent
        self.image = image
        self.on_update = on_update_callback
        self.logger = get_logger(__name__)
        
        # 通道状态
        self.channel_r_var = tk.BooleanVar(value=True)
        self.channel_g_var = tk.BooleanVar(value=True)
        self.channel_b_var = tk.BooleanVar(value=True)
        
        # 通道权重
        self.weight_r_var = tk.DoubleVar(value=1.0)
        self.weight_g_var = tk.DoubleVar(value=1.0)
        self.weight_b_var = tk.DoubleVar(value=1.0)
        
        # 预览模式
        self.preview_mode_var = tk.StringVar(value="combined")
        
        # 分离通道
        self.channel_r = image[:, :, 0]
        self.channel_g = image[:, :, 1]
        self.channel_b = image[:, :, 2]
        
        # 创建控制面板
        self._create_controls()
    
    def _create_controls(self):
        """创建控制面板"""
        # 红色通道
        r_frame = self._create_channel_control(
            self.parent, "红色通道 (R)", 
            self.channel_r_var, self.weight_r_var, "#ff4444"
        )
        r_frame.pack(fill=tk.X, pady=5)
        
        # 绿色通道
        g_frame = self._create_channel_control(
            self.parent, "绿色通道 (G)",
            self.channel_g_var, self.weight_g_var, "#44ff44"
        )
        g_frame.pack(fill=tk.X, pady=5)
        
        # 蓝色通道
        b_frame = self._create_channel_control(
            self.parent, "蓝色通道 (B)",
            self.channel_b_var, self.weight_b_var, "#4444ff"
        )
        b_frame.pack(fill=tk.X, pady=5)
        
        # 分隔线
        ttk.Separator(self.parent, orient=tk.HORIZONTAL).pack(fill=tk.X, pady=15)
        
        # 预览模式选择
        self._create_preview_mode_selector()
        
        # 快捷按钮
        ttk.Separator(self.parent, orient=tk.HORIZONTAL).pack(fill=tk.X, pady=15)
        self._create_quick_buttons()
        
        # 重置按钮
        ttk.Button(
            self.parent,
            text="重置为默认",
            command=self.reset_to_default,
            width=30
        ).pack(pady=10)
    
    def _create_channel_control(
        self,
        parent: ttk.Frame,
        label: str,
        enabled_var: tk.BooleanVar,
        weight_var: tk.DoubleVar,
        color: str
    ) -> ttk.Frame:
        """创建单个通道控制"""
        frame = ttk.LabelFrame(parent, text=label, padding=5)
        
        # 启用复选框
        check = ttk.Checkbutton(
            frame,
            text="启用",
            variable=enabled_var,
            command=self.on_update
        )
        check.pack(anchor=tk.W, pady=2)
        
        # 权重滑块
        weight_frame = ttk.Frame(frame)
        weight_frame.pack(fill=tk.X, pady=5)
        
        ttk.Label(weight_frame, text="权重:", width=6).pack(side=tk.LEFT)
        
        scale = ttk.Scale(
            weight_frame,
            from_=0.0,
            to=2.0,
            orient=tk.HORIZONTAL,
            variable=weight_var,
            command=lambda v: self._on_weight_change()
        )
        scale.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=5)
        
        value_label = ttk.Label(weight_frame, text="1.00", width=5)
        value_label.pack(side=tk.LEFT)
        
        # 保存标签引用以便更新
        frame.value_label = value_label
        frame.weight_var = weight_var
        
        return frame
    
    def _create_preview_mode_selector(self):
        """创建预览模式选择器"""
        ttk.Label(self.parent, text="预览模式:", font=("Arial", 10, "bold")).pack(anchor=tk.W, pady=(5, 2))
        
        preview_modes = [
            ("组合视图", "combined"),
            ("仅红色通道", "r_only"),
            ("仅绿色通道", "g_only"),
            ("仅蓝色通道", "b_only"),
            ("灰度视图", "grayscale")
        ]
        
        for text, value in preview_modes:
            ttk.Radiobutton(
                self.parent,
                text=text,
                variable=self.preview_mode_var,
                value=value,
                command=self.on_update
            ).pack(anchor=tk.W, pady=2)
    
    def _create_quick_buttons(self):
        """创建快捷按钮"""
        ttk.Label(self.parent, text="快捷操作:", font=("Arial", 10, "bold")).pack(anchor=tk.W, pady=(5, 5))
        
        quick_btn_frame = ttk.Frame(self.parent)
        quick_btn_frame.pack(fill=tk.X, pady=5)
        
        ttk.Button(
            quick_btn_frame,
            text="全选",
            command=self.select_all_channels,
            width=10
        ).pack(side=tk.LEFT, padx=2)
        
        ttk.Button(
            quick_btn_frame,
            text="全不选",
            command=self.deselect_all_channels,
            width=10
        ).pack(side=tk.LEFT, padx=2)
        
        ttk.Button(
            quick_btn_frame,
            text="反选",
            command=self.invert_channels,
            width=10
        ).pack(side=tk.LEFT, padx=2)
    
    def _on_weight_change(self):
        """权重变化回调"""
        # 更新所有权重标签
        for widget in self.parent.winfo_children():
            if hasattr(widget, 'value_label') and hasattr(widget, 'weight_var'):
                widget.value_label.config(text=f"{widget.weight_var.get():.2f}")
        
        # 更新预览
        self.on_update()
    
    def generate_combined_image(self) -> np.ndarray:
        """生成组合通道图像"""
        use_r = self.channel_r_var.get()
        use_g = self.channel_g_var.get()
        use_b = self.channel_b_var.get()
        
        weight_r = self.weight_r_var.get()
        weight_g = self.weight_g_var.get()
        weight_b = self.weight_b_var.get()
        
        h, w = self.image.shape[:2]
        result = np.zeros((h, w, 3), dtype=np.uint8)
        
        if use_r:
            result[:, :, 0] = np.clip(self.channel_r * weight_r, 0, 255).astype(np.uint8)
        
        if use_g:
            result[:, :, 1] = np.clip(self.channel_g * weight_g, 0, 255).astype(np.uint8)
        
        if use_b:
            result[:, :, 2] = np.clip(self.channel_b * weight_b, 0, 255).astype(np.uint8)
        
        return result
    
    def get_preview_image(self) -> np.ndarray:
        """获取预览图像"""
        mode = self.preview_mode_var.get()
        use_r = self.channel_r_var.get()
        use_g = self.channel_g_var.get()
        use_b = self.channel_b_var.get()
        
        if mode == "combined":
            preview = self.generate_combined_image()
        elif mode == "r_only":
            preview = np.stack([self.channel_r] * 3, axis=-1) if use_r else np.zeros_like(self.image)
        elif mode == "g_only":
            preview = np.stack([self.channel_g] * 3, axis=-1) if use_g else np.zeros_like(self.image)
        elif mode == "b_only":
            preview = np.stack([self.channel_b] * 3, axis=-1) if use_b else np.zeros_like(self.image)
        elif mode == "grayscale":
            preview = self.generate_combined_image()
            preview = cv2.cvtColor(preview, cv2.COLOR_RGB2GRAY)
            preview = np.stack([preview] * 3, axis=-1)
        else:
            preview = self.generate_combined_image()
        
        return preview
    
    def get_channel_config(self) -> dict:
        """获取通道配置信息"""
        return {
            'enabled_channels': {
                'r': self.channel_r_var.get(),
                'g': self.channel_g_var.get(),
                'b': self.channel_b_var.get()
            },
            'weights': {
                'r': self.weight_r_var.get(),
                'g': self.weight_g_var.get(),
                'b': self.weight_b_var.get()
            }
        }
    
    def get_info_text(self) -> str:
        """获取信息文本"""
        use_r = self.channel_r_var.get()
        use_g = self.channel_g_var.get()
        use_b = self.channel_b_var.get()
        
        weight_r = self.weight_r_var.get()
        weight_g = self.weight_g_var.get()
        weight_b = self.weight_b_var.get()
        
        enabled_channels = []
        if use_r:
            enabled_channels.append(f"R({weight_r:.1f})")
        if use_g:
            enabled_channels.append(f"G({weight_g:.1f})")
        if use_b:
            enabled_channels.append(f"B({weight_b:.1f})")
        
        if enabled_channels:
            return f"启用通道: {', '.join(enabled_channels)}"
        else:
            return "⚠️ 警告：未启用任何通道"
    
    def is_valid(self) -> bool:
        """检查配置是否有效"""
        return (self.channel_r_var.get() or 
                self.channel_g_var.get() or 
                self.channel_b_var.get())
    
    def select_all_channels(self):
        """全选所有通道"""
        self.channel_r_var.set(True)
        self.channel_g_var.set(True)
        self.channel_b_var.set(True)
        self.on_update()
    
    def deselect_all_channels(self):
        """取消所有通道"""
        self.channel_r_var.set(False)
        self.channel_g_var.set(False)
        self.channel_b_var.set(False)
        self.on_update()
    
    def invert_channels(self):
        """反选通道"""
        self.channel_r_var.set(not self.channel_r_var.get())
        self.channel_g_var.set(not self.channel_g_var.get())
        self.channel_b_var.set(not self.channel_b_var.get())
        self.on_update()
    
    def reset_to_default(self):
        """重置为默认"""
        self.channel_r_var.set(True)
        self.channel_g_var.set(True)
        self.channel_b_var.set(True)
        self.weight_r_var.set(1.0)
        self.weight_g_var.set(1.0)
        self.weight_b_var.set(1.0)
        self.preview_mode_var.set("combined")
        self._on_weight_change()
        self.on_update()

